#if NETFX_CORE
using TcpClient = Windows.Networking.Sockets.StreamSocket;
using EndPoint = Windows.Networking.HostName;
#else
using System.Net.Sockets;
#endif
using XcoAppSpaces.Transport.Sockets.Auth.Contract;
using XcoAppSpaces.Transport.Sockets.Auth.Contract.DoServerHandshake;

namespace XcoAppSpaces.Transport.Sockets.Auth
{
	class DoServerHandshake : IDoHandshake
	{
		private IPrepareAuthentication prepareAuthentication;
		private IReceiveGreeting receiveGreeting;
		private ISendChallenge sendChallenge;
		private IReceiveResponse receiveResponse;
		private IFinishAuthentication finishAuthentication;

		public DoServerHandshake(IPrepareAuthentication prepareAuthentication, IReceiveGreeting receiveGreeting, ISendChallenge sendChallenge, IReceiveResponse receiveResponse, IFinishAuthentication finishAuthentication)
		{
			this.prepareAuthentication = prepareAuthentication;
			this.receiveGreeting = receiveGreeting;
			this.sendChallenge = sendChallenge;
			this.receiveResponse = receiveResponse;
			this.finishAuthentication = finishAuthentication;

			prepareAuthentication.Out_Connection += receiveGreeting.In_Connection;
			receiveGreeting.Out_ValidConnection += sendChallenge.In_Connection;
			sendChallenge.Out_ValidConnection += receiveResponse.In_Connection;
			receiveResponse.Out_ValidConnection += finishAuthentication.In_Connection;
			finishAuthentication.Out_TcpClient += _ => this.Out_AuthenticatedConnection(_);

			prepareAuthentication.Out_Error += _ => this.Out_InvalidConnection(_);
			receiveGreeting.Out_InvalidConnection += _ => this.Out_InvalidConnection(_);
			sendChallenge.Out_InvalidConnection += _ => this.Out_InvalidConnection(_);
			receiveResponse.Out_InvalidConnection += _ => this.Out_InvalidConnection(_);
		}

		public void In_Connection(TcpClient tcpClient)
		{
			prepareAuthentication.In_TcpClient(tcpClient);
		}

        public event TcpClientHandler Out_AuthenticatedConnection;

        public event TcpClientHandler Out_InvalidConnection;

		public void Inject(SecuritySettings dependency)
		{
			prepareAuthentication.Inject(dependency);
			receiveGreeting.Inject(dependency);
			sendChallenge.Inject(dependency);
			receiveResponse.Inject(dependency);
		}
	}
}
